package com.geek.novel.utils

import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.hardware.Camera
import android.net.ConnectivityManager
import android.provider.Settings
import android.telephony.TelephonyManager
import android.text.TextUtils
import android.util.TypedValue
import android.view.inputmethod.InputMethodManager
import com.geek.novel.bo.AppContext
import com.geek.novel.common.Constant
import io.reactivex.ObservableTransformer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.math.BigDecimal
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern

/**
 * Created by  on 2017/8/15.
 */
object CommUtil {
	
	val screenHeight: Int
		get() = AppContext.getContext().resources.displayMetrics.heightPixels
	val ScreenWidth: Int
		get() = AppContext.getContext().resources.displayMetrics.widthPixels


	/**
	 * 获取版本号
	 */
	fun getVersion(): PackageInfo?{
		val packageManager: PackageManager = AppContext.getContext().packageManager
		try {
			return packageManager.getPackageInfo(AppContext.getContext().packageName, 0)
		} catch (e: PackageManager.NameNotFoundException) {
			e.printStackTrace()
		}
		return null
	}

	/**获取用户的本地图片文件名*/
	fun getUserHeaderImageName(): String?{
		val user = SecurityUtil.getPrincipal() ?: return null
		return "header_${user.id}"
	}

	/**
	 * 判断Activity是否活跃
	 */
	fun isActivityActive(context: Context): Boolean{
		val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
		val topActivity = activityManager.getRunningTasks(1).get(0).topActivity
		val className = topActivity.className
		if(!TextUtils.isEmpty(className) && className.equals(context.javaClass.name)){
			return true
		}
		return false
	}

	/**
	 * 判断字符串是不是浮点数字
	 * @param number
	 * *
	 * @return
	 */
	fun isFloatNum(number: String): Boolean {
		try {
			java.lang.Float.valueOf(number)
			return true
		} catch (e: Exception) {
			return false
		}
		
	}
	
	private var isExit = false
	
	fun exitBy2Click() {
		val tExit: Timer
		if (!isExit) {
			isExit = true // 准备退出
//            ToastUtils.toast("再按一次退出程序")
			ToastUtils.toast("再按一次退出程序")
			
			tExit = Timer()
			tExit.schedule(object : TimerTask() {
				override fun run() {
					isExit = false // 取消退出
				}
			}, 2000) // 如果2秒钟内没有按下返回键，则启动定时器取消掉刚才执行的任务
		} else {
			System.exit(0)
			System.exit(0)
		}
	}
	
	
	fun s2HMS(_ms: Long?): String {
		val HMStime: String
		val hour = _ms!! / 3600
		val mint = _ms % 3600 / 60
		val sed = _ms % 60
		var hourStr = hour.toString()
		if (hour < 10) {
			hourStr = "0" + hourStr
		}
		var mintStr = mint.toString()
		if (mint < 10) {
			mintStr = "0" + mintStr
		}
		var sedStr = sed.toString()
		if (sed < 10) {
			sedStr = "0" + sedStr
		}
		HMStime = hourStr + "时" + mintStr + "分" + sedStr + "秒"
		return HMStime
	}
	
	/**
	 * 校验银行卡卡号
	 * @param cardId
	 * *
	 * @return
	 */
	fun checkBankCard(cardId: String): Boolean {
		val bit = getBankCardCheckCode(cardId.substring(0, cardId.length - 1))
		if (bit == 'N') {
			return false
		}
		return cardId[cardId.length - 1] == bit
	}
	
	fun getRandColorCode(): String {
		var r: String
		var g: String
		var b: String
		val random = Random()
		r = Integer.toHexString(random.nextInt(256)).toUpperCase()
		g = Integer.toHexString(random.nextInt(256)).toUpperCase()
		b = Integer.toHexString(random.nextInt(256)).toUpperCase()
		
		r = if (r.length == 1) "0" + r else r
		g = if (g.length == 1) "0" + g else g
		b = if (b.length == 1) "0" + b else b
		
		return r + g + b
	}
	
	
	/**
	 * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
	 * @param nonCheckCodeCardId
	 * *
	 * @return
	 */
	fun getBankCardCheckCode(nonCheckCodeCardId: String?): Char {
		if (nonCheckCodeCardId == null || nonCheckCodeCardId.trim { it <= ' ' }.length == 0
				|| !nonCheckCodeCardId.matches("\\d+".toRegex())) {
			//如果传的不是数据返回N
			return 'N'
		}
		val chs = nonCheckCodeCardId.trim { it <= ' ' }.toCharArray()
		var luhmSum = 0
		var i = chs.size - 1
		var j = 0
		while (i >= 0) {
			var k = chs[i] - '0'
			if (j % 2 == 0) {
				k *= 2
				k = k / 10 + k % 10
			}
			luhmSum += k
			i--
			j++
		}
		return if (luhmSum % 10 == 0) '0' else "${(10 - luhmSum % 10)}0".single()
	}
	
	val isLogin: Boolean
		get() = SPUtil[Constant.SP_IS_LOGIN, false, SPUtil.usrInfo] as Boolean
	

	/**
	 * 密码(以字母开头，长度在6~18之间，只能包含字母、数字和下划线)
	 
	 * @param password 密码
	 * *
	 * @return 密码是否符合要求
	 */
	fun PasswordCheck(password: String): Boolean {
		val telRegex = "^[a-zA-Z0-9]\\w{5,20}$"
		val pattern = Pattern.compile(telRegex)
		val checkMatcher = pattern.matcher(password)
		return checkMatcher.matches()
	}
	
	fun isEMailAdd(emailadd: String): Boolean {
		val telRegex = "^(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w+)+)$"
		val pattern = Pattern.compile(telRegex)
		val checkMatcher = pattern.matcher(emailadd)
		return checkMatcher.matches()
	}
	
	val isNetConn: Boolean
		get() = NetCheckTool.isNetworkAvailable(AppContext.getContext())
	
	/**
	 * 时间戳转日期
	 * @param timeStamp
	 * *
	 * @return
	 */
	fun timeStampToDate(timeStamp: Long): String {
		val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
		val date = sdf.format(timeStamp * 1000)
		return date
	}
	
	fun mul(v1: String?, v2: String?): String {
		if (isNull(v1) || isNull(v2))
			return ""
		val b1 = BigDecimal(v1)
		val b2 = BigDecimal(v2)
		return b1.multiply(b2).toString()
	}
	
	/**
	 * 校验字符串是不是电话号码
	 
	 * @param mobiles 要校验的字符串
	 * *
	 * @return true是电话号码，false不是电话号码
	 */
	fun isMobile(mobiles: String): Boolean {
		if (mobiles.length != 11)
			return false
		val telRegex = "[1]\\d{10}"
		return mobiles.matches(telRegex.toRegex())
	}
	
	fun add(v1: String, v2: String): String {
		if (isNull(v1) || isNull(v2))
			return ""
		val b1 = BigDecimal(v1)
		val b2 = BigDecimal(v2)
		return b1.add(b2).toString()
	}
	
	/**
	 * 校验字符串是不是整形数字
	 
	 * @param str 字符串
	 * *
	 * @return true 是整形数字，false不是整形数字
	 */
	fun isNumeric(str: String?): Boolean {
		if (str == null || "" == str)
			return false
		try {
			val pattern = Pattern.compile("[0-9]*")
			val isNum = pattern.matcher(str)
			if (!isNum.matches()) {
				return false
			}
		} catch (e: Exception) {
			return false
		}
		
		return true
		
	}

	fun getNumeric(str: String?): Long{
		var result = 0L
		if(!isNumeric(str)){
			return result
		}
		try {
			val pattern = Pattern.compile("[^0-9]")
			val matcher = pattern.matcher(str)
			val all: String = matcher.replaceAll("")
			result = all.toLong()
		} catch (e: Exception) {
			LogCatUtil.e("CommUtil", e.message!!, e)
		}
		return result
	}

	/**
	 * 统一格式化数字,保留1位小数
	 
	 * @param value
	 * *
	 * @return
	 */
	fun getDecimalFormat(value: Double): String {
		try {
			return DecimalFormat("####0.0").format(value)
		} catch (e: Exception) {
			return ""
		}
	}
	
	/**
	 * 统一格式化数字,保留2位小数
	 
	 * @param value
	 * *
	 * @return
	 */
	fun getDecimalFormat2(value: Double): String {
		try {
			return DecimalFormat("####0.00").format(value)
		} catch (e: Exception) {
			return ""
		}
	}
	
	/**
	 * 把秒数转换成时分秒
	 
	 * @param second 秒数
	 * *
	 * @return
	 */
	fun second2hms(second: Long): String {
		var h = 0
		var d = 0
		var s = 0
		val temp = (second % 3600).toInt()
		if (second > 3600) {
			h = (second / 3600).toInt()
			if (temp != 0) {
				if (temp > 60) {
					d = temp / 60
					if (temp % 60 != 0) {
						s = temp % 60
					}
				} else {
					s = temp
				}
			}
		} else {
			d = (second / 60).toInt()
			if (second % 60 != 0L) {
				s = (second % 60).toInt()
			}
		}
		return h.toString() + "时" + d + "分" + s + "秒"
	}
	
	fun compare_date(DATE1: String, DATE2: String): Int {
		val df = SimpleDateFormat("yyyy-MM")
		try {
			val dt1 = df.parse(DATE1)
			val dt2 = df.parse(DATE2)
			if (dt1.time > dt2.time) {
				return 1//dt1 在dt2前
			} else if (dt1.time < dt2.time) {
				return -1//dt1在dt2后
			} else {
				return 0
			}
		} catch (exception: Exception) {
			exception.printStackTrace()
		}
		
		return 0
	}
	
	fun <T : Any?> compose(): ObservableTransformer<T, T> {
		return ObservableTransformer<T, T> { observable ->
			observable.subscribeOn(Schedulers.io())?.doOnSubscribe { LogCatUtil.d("", "=============acceptdisposable=") }?.observeOn(AndroidSchedulers.mainThread())!!;
		};
	}
	
	/**
	 * 数字字符串转成浮点数字符串
	 * @param number 数字字符串
	 *
	 */
	fun float2String(number: String): String = number
	
	/**
	 * 对float数组进行冒泡排序
	 
	 * @param data float数组
	 */
	fun sort(data: FloatArray) {
		val len = data.size
		for (i in 0 until len - 1) {
			var temp: Float
			var isExchanged = false
			for (j in 0 until len - i - 1) {
				if (data[j] > data[j + 1]) {
					temp = data[j]
					data[j] = data[j + 1]
					data[j + 1] = temp
					isExchanged = true
				}
			}
			if (!isExchanged) {
				break
			}
		}
	}
	
	/**
	 * 隐藏软键盘
	 
	 * @param context
	 */
	fun hideKeyboard(context: Activity?) {
		if (null != context) {
			val imm = context
					.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
			if (null != context.currentFocus)
				imm.hideSoftInputFromWindow(context.currentFocus!!
						.windowToken, 0)
			
		}
	}
	
	/**
	 * 得到设备的密度
	 */
	private fun getScreenDensity(context: Context): Float = context.resources.displayMetrics.density
	
	fun dip2px(dp: Float): Float {
		return dip2px(dp, AppContext.getContext())
	}

	fun dip2px(dp: Float, context: Context): Float {
//        val scale = getScreenDensity(AppContext.getContext())
//        return (dp * scale + 0.5).toInt()
		return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.resources.displayMetrics)
	}

	fun px2dip(px: Float): Float {
		return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, px, AppContext.getContext().resources.displayMetrics)
	}

	fun isNull(s: String?): Boolean {
		if (null == s || "" == s || "null" == s) {
			return true
		}
		return false
	}
	
	// setParameters 是针对魅族MX5。MX5通过Camera.open()拿到的Camera对象不为null
	val isCameraCanUse: Boolean
		get() {
			var canUse = true
			
			var mCamera: Camera? = null
			
			try {
				
				mCamera = Camera.open()
				
				val mParameters = mCamera!!.parameters
				
				mCamera.parameters = mParameters
				
			} catch (e: Exception) {
				
				canUse = false
				
			}
			
			if (mCamera != null) {
				
				mCamera.release()
				
			}
			return canUse
		}
	
	/**
	 * 判断wifi是否连接状态
	 *
	 *
	 * 需添加权限
	 * `<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>`
	 *
	 
	 * @param context 上下文
	 * *
	 * @return `true`: 连接<br></br>
	 * * `false`: 未连接
	 */
	fun isWifiConnected(context: Context): Boolean {
		val cm = context
				.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
		return cm.activeNetworkInfo != null
				&& cm.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
	}

	val deviceId: String?
		get() {
			val user = SecurityUtil.getPrincipal()
			//获取当前用户的手机号或者用设备号
			return if(user != null){
				user.phone
			}else{
				deviceUuid
			}
		}
	
	val deviceUuid: String?
		@SuppressLint("HardwareIds")
		get() {
			val uuid: UUID
			val id = SPUtil[Constant.SP_DEVICE_ID, "", SPUtil.sysInfo] as String
			
			if (!isNull(id)) {
				uuid = UUID.fromString(id)
			} else {
				
				val androidId = Settings.Secure.getString(
						AppContext.getContext().contentResolver,
						Settings.Secure.ANDROID_ID)
				
				try {
					
					if ("9774d56d682e549c" != androidId) {
						
						uuid = UUID.nameUUIDFromBytes(androidId.toByteArray(charset("utf8")))
						
					} else {
						
						val deviceId = (AppContext.getContext()
								.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager)
								.deviceId
						
						uuid = if (deviceId != null)
							UUID.nameUUIDFromBytes(deviceId
									.toByteArray(charset("utf8")))
						else
							UUID.randomUUID()
						
					}
					
				} catch (e: SecurityException) {
					return null
				}
				
				SPUtil.put(Constant.SP_DEVICE_ID, uuid.toString(), SPUtil.sysInfo)
				return uuid.toString()
			}
			if (uuid != null)
				return uuid.toString()
			return null
			
		}
	
	private fun capitalize(str: String): String? {
		if (TextUtils.isEmpty(str)) {
			return str
		}
		val arr = str.toCharArray()
		var capitalizeNext = true
		
		val phrase = StringBuilder()
		for (c in arr) {
			if (capitalizeNext && Character.isLetter(c)) {
				phrase.append(Character.toUpperCase(c))
				capitalizeNext = false
				continue
			} else if (Character.isWhitespace(c)) {
				capitalizeNext = true
			}
			phrase.append(c)
		}
		
		return phrase.toString()
	}
	
	/**
	 * 设置用户配置信息
	 
	 * @param key   key值
	 * *
	 * @param value key所对应的字符串值
	 */
	fun setUserSetting(key: String, value: String) {
		SPUtil.put(key, value, "UserSetting")
	}
	
	/**
	 * 获取当前用户账号
	 
	 * @return 当前用户账号
	 */
	/**
	 * 设置当前用户账号
	 
	 * @param account 当前用户账号
	 */
	var account: String
		get() = SPUtil[Constant.SP_USERINFO_ACCOUNT, "", "UserSetting"] as String
		set(account) {
			SPUtil.put(Constant.SP_USERINFO_ACCOUNT, account, "UserSetting")
		}
	
}

